#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <limits.h>
#include <sys/stat.h>

#define PICTURES_DIR "~/Pictures"
#define FEH_CMD "feh --bg-fill %s"
#define BLACK_BG "/dev/null"  // Feh treats /dev/null as black background

// Expand tilde in path (e.g., ~/Pictures -> /home/user/Pictures)
char* expand_tilde(const char* path) {
    if (path[0] != '~') {
        char* res = strdup(path);
        return res;
    }

    const char* home = getenv("HOME");
    if (!home) {
        fprintf(stderr, "Error: HOME environment variable not set\n");
        return NULL;
    }

    char* expanded = malloc(strlen(home) + strlen(path) + 1);
    if (!expanded) {
        perror("malloc failed");
        return NULL;
    }

    strcpy(expanded, home);
    strcat(expanded, path + 1);  // Skip the tilde
    return expanded;
}

// List image files in ~/Pictures (supports common formats)
void list_images() {
    char* pics_dir = expand_tilde(PICTURES_DIR);
    if (!pics_dir) return;

    DIR* dir = opendir(pics_dir);
    if (!dir) {
        perror("Failed to open Pictures directory");
        free(pics_dir);
        return;
    }

    struct dirent* entry;
    const char* extensions[] = {".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", NULL};
    printf("Available images in %s:\n", pics_dir);

    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_name[0] == '.') continue;  // Skip hidden files

        // Check if file has an image extension
        for (int i = 0; extensions[i]; i++) {
            size_t len = strlen(entry->d_name) - strlen(extensions[i]);
            if (len > 0 && strcmp(entry->d_name + len, extensions[i]) == 0) {
                printf("  - %s\n", entry->d_name);
                break;
            }
        }
    }

    closedir(dir);
    free(pics_dir);
}

// Set background using feh
int set_background(const char* image_path) {
    char cmd[PATH_MAX + strlen(FEH_CMD) + 1];
    snprintf(cmd, sizeof(cmd), FEH_CMD, image_path);

    int result = system(cmd);
    if (result != 0) {
        fprintf(stderr, "Failed to set background with command: %s\n", cmd);
        return -1;
    }
    printf("Background set to: %s\n", image_path);
    return 0;
}

// Show usage instructions
void print_usage(const char* prog_name) {
    printf("\n%s is a program for watching your $HOME/Pictures folder for images and let feh program setup background image\n", prog_name); 
    printf("\nUsage: %s [COMMAND] [IMAGE_NAME]\n", prog_name);
    printf("Commands:\n");
    printf("  list         List all images in ~/Pictures\n");
    printf("  set [NAME]   Set background to image from ~/Pictures (use exact filename)\n");
    printf("  help         Show this help message\n");
}

int main(int argc, char* argv[]) {
    // Default: set black background if no arguments
    if (argc == 1) {
        print_usage(argv[0]);
    }

    
    if (strcmp(argv[1], "list") == 0) {
        list_images();
        return 0;
    }
    else if (strcmp(argv[1], "set") == 0) {
        if (argc != 3) {
            fprintf(stderr, "Error: Please specify an image name\n");
            print_usage(argv[0]);
            return 1;
        }

        // Build full path to image
        char* pics_dir = expand_tilde(PICTURES_DIR);
        if (!pics_dir) return 1;

        char image_path[PATH_MAX];
        snprintf(image_path, sizeof(image_path), "%s/%s", pics_dir, argv[2]);
        free(pics_dir);

        // Check if image exists
        struct stat st;
        if (stat(image_path, &st) != 0) {
            fprintf(stderr, "Error: Image not found - %s\n", image_path);
            return 1;
        }

        return set_background(image_path);
    }
    else if (strcmp(argv[1], "help") == 0) {
        print_usage(argv[0]);
        return 0;
    }
    else {
        fprintf(stderr, "Error: Unknown command - %s\n", argv[1]);
        print_usage(argv[0]);
        return 1;
    }
}
